package cn.agiledata.bank.linkbank.impl.cib;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import cn.agiledata.bank.account.service.ISequenceGenerator;
import cn.agiledata.bank.linkbank.impl.AbstractBankPayResponse;
import cn.agiledata.bank.linkbank.logic.CryptoKeyValidator;
import cn.agiledata.bank.linkbank.logic.DigitalSignValidatable;

/**
 * 中国兴业银行网上银行支付响应
 * 
 * @author 马贤波
 * 
 */
public final class CibNetPayResponse extends AbstractBankPayResponse
		implements DigitalSignValidatable {

	/**
     * 银行响应关键字组
     */
	private static final String[] RESPONSE_KEYS = {
			CibNetConstant.RESPONSE_MERCHANT_ID,
			CibNetConstant.RESPONSE_ORDER_ID, CibNetConstant.RESPONSE_AMOUNT,
			CibNetConstant.RESPONSE_CURRENCY_TYPE,
			CibNetConstant.RESPONSE_EBANK_TRACE_ID,
			CibNetConstant.RESPONSE_RETURN_CODE };

	private CibOrderIdTransformer orderIdTransformer;

	private CryptoKeyValidator cryptoKeyValidator;

	public CibNetPayResponse() {
		super();
		this.orderIdTransformer = new CibOrderIdTransformer();
		this.cryptoKeyValidator = new CibCryptoKeyValidator();
	}

	protected AbstractBankPayResponse getCopiedInstance() {
		CibNetPayResponse response = new CibNetPayResponse();
		response.orderIdTransformer = this.orderIdTransformer;
		response.cryptoKeyValidator = this.cryptoKeyValidator;
		return response;
	}

	public void setSequenceGenerator(ISequenceGenerator sequenceGenerator) {
		this.orderIdTransformer.setSequenceGenerator(sequenceGenerator);
	}

	protected String getSuccessReturnCode() {
		return CibNetConstant.RETURN_CODE_SUCCESS;
	}

	protected String[] getValidKeys() {
		return RESPONSE_KEYS;
	}

	protected boolean isValidKey(String key) {
		if (CibNetConstant.RESPONSE_MAC.equals(key)) {
			return true;
		}
		return super.isValidKey(key);
	}

	public BigDecimal getAmount() {
		try {
			return new BigDecimal(getMessage(CibNetConstant.RESPONSE_AMOUNT));
		} catch (Exception e) {
			return null;
		}
	}

	public String getOrderId() {
		String orderId = getMessage(CibNetConstant.RESPONSE_ORDER_ID);
		return this.orderIdTransformer.orderId2TransId(orderId);
	}

	public String getReturnCode() {
		return getMessage(CibNetConstant.RESPONSE_RETURN_CODE);
	}

	public String getDigitalSign() {
		return getMessage(CibNetConstant.RESPONSE_MAC);
	}

	public String getCryptoKeyDescription() {
		return this.cryptoKeyValidator.getCryptoKeyDescription();
	}

	public boolean validateCryptoKey(String cryptoKey) {
		return this.cryptoKeyValidator.validateCryptoKey(cryptoKey);
	}

	public boolean validateDigitalSign(String cryptoKey) {
		Map values = new HashMap();
		String[] keys = RESPONSE_KEYS;
		for (int i = 0; i < keys.length; i++) {
			values.put(keys[i], getMessage(keys[i]));
		}
		return CibUtils.validateMac(values, keys, cryptoKey, getDigitalSign());
	}

}
